package polimi.sc.expoquest.storage;

import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteException;
import android.database.sqlite.SQLiteOpenHelper;
/**
 * This class is in charge of accessing directly the database.
 * Such as creation, updates, upgrades, etc.
 * @author Monica Lozano
 *
 */
public class DBHelper extends SQLiteOpenHelper {
	
	//-------------------------------
	// CONSTANTS
	//-------------------------------
	
	/*
	 * The version of the database
	 */
	public static final int DATABASE_VERSION=1;
	/*
	 * Name of the database, the one we want to put it or we already assigned
	 */
	public static final String DATABASE_NAME="expoquest.sqlite";
	/*
	 * The path to the database, when it doesn't exist previously is not necessary to
	 * define a path, the framework automatically saved it in DATA/data/APP_NAME/databases/FILENAME
	 * TODO put DATA as parametric in the general database path: DATA/data/APP_NAME/databases/FILENAME.
	 * TODO DATA= Environment.getDataDirectory();
	 * APP_NAME=polimi.sc.expoquest
	 * FILENAME= DATABASE_NAME
	 */
	public static final String DATABASE_PATH="/data/data/polimi.sc.expoquest/databases/";
	
	//------------------------
	// ATTRIBUTTES
	//------------------------
	/*
	 * The object that represents our database
	 */
	private SQLiteDatabase mDb;
	/*
	 * The context of the application in the framework
	 */
	private final Context ctx;
	/*
	 * The path to the database 
	 */
	private String path;
	
	
	//-------------------------
	// CONSTRUCTOR
	//-------------------------
	public DBHelper(Context context) {
		super(context, DATABASE_NAME, null, DATABASE_VERSION);
		ctx= context;
		path= DATABASE_PATH+DATABASE_NAME;
	}
	
	//------------------------
	// PROPIETARY METHODS
	//------------------------
	
	public void open(){
		
		//1. Creating the database
		try {
			createDatabase();
		} catch (IOException e) {
			throw new Error("ERROR: The database could not have been created");
		}
		//2. Opening and acquiring access to the object of the database
		//TODO delete it or use it
		mDb=SQLiteDatabase.openDatabase(path, null, SQLiteDatabase.OPEN_READONLY);
		
	}
	
	
	public void createDatabase() throws IOException{
		//1. check that the database already exists
		boolean dbExists= checkDatabase();
		//2. Evaluating result
		if(!dbExists)
		{
			//3. We need to copy our database into the application
			//3.1 Creating an empty database
			this.getReadableDatabase();
			//3.2 We copy our existing database into the empty database
			try{
				copyData();
			}
			catch(IOException e){
				throw new Error("ERROR: Copying the database");
			}
		}
		//UNCOMMENT: Use in case of DEVELOPING AND WANT TO UPDATE THE DATABASE DATA
		/*
		 else{
		 
			try{
				copyData();
			}
			catch(IOException e){
				throw new Error("ERROR: Copying the database");
			}
		}
		*/
		
	}
	/**
	 * Checks if the database already exists in the framework
	 * @return
	 */
	public boolean checkDatabase(){
		
		SQLiteDatabase checkDB = null; 
		boolean exists = false;
		try{
			//1. We try to open the database
			checkDB = SQLiteDatabase.openDatabase(path, null, SQLiteDatabase.OPEN_READONLY);
		}
		catch(SQLiteException ex)
		{
			//The database doesnt exists
		}
		if(checkDB != null){
			checkDB.close();
			exists=true;
		}
		return exists;
	}
	
	/**
	 * Copy the data from our original database to the database that the framework automatically
	 * creates
	 * @throws IOException 
	 */
	public void copyData() throws IOException{
			//1. We open the database file
			InputStream in = ctx.getAssets().open(DATABASE_NAME);
			 
			//2.We open the empty database that we just created 
			OutputStream out = new FileOutputStream(path);
			 
			//3. We copy the data from our database to the empty one in the framework
			byte[] buffer = new byte[1024];
			int length;
			while ((length = in.read(buffer))>0){
			out.write(buffer, 0, length);
			}
			 
			//4. Closing streams
			out.flush();
			out.close();
			in.close();		 
	}
	
	//------------------------
	// OVERRIDE METHODS
	//------------------------
	
	@Override
	/* 
	 * This is called IF the database does not exists
	 * (non-Javadoc)
	 * @see android.database.sqlite.SQLiteOpenHelper#onCreate(android.database.sqlite.SQLiteDatabase)
	 */
	public void onCreate(SQLiteDatabase arg0) {
		// TODO Auto-generated method stub

	}

	@Override
	/* This is called IF the database changes of version in the application
	 * (non-Javadoc)
	 * @see android.database.sqlite.SQLiteOpenHelper#onUpgrade(android.database.sqlite.SQLiteDatabase, int, int)
	 */
	public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
		// TODO Auto-generated method stub

	}
	@Override
	/*
	 * Closing the database
	 * (non-Javadoc)
	 * @see android.database.sqlite.SQLiteOpenHelper#close()
	 */
	public synchronized void close() {
		if(mDb != null)
			mDb.close();
		super.close();
	}

}
